using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;

using Deepcode.Flux.Core.Systems.Workflow;
using Deepcode.Flux.Core.Systems.Workflow.Bases;
using Deepcode.Flux.Core.Systems.Workflow.Info;
using Deepcode.Flux.Core.Services.State;
using Deepcode.Flux.Core.Extensions;
using Deepcode.Flux.Core.Systems.Audit.Quick;

public partial class Private_Config_Workflow_ui_processform : Deepcode.Flux.Core.UI.AdministrationModulePage
{
	#region Permission Code Override
	public override string RequiredPermissionCode { get { return "FluxWorkflowEdit"; } }
	#endregion
	#region ViewState storage
	/// <summary>
	/// Stores the ID of the handler which this form
	/// is adding a new definition to.
	/// </summary>
	public string HandlerID
	{
		get
		{
			object o = ViewState["HandlerID"];
			if (o == null) return String.Empty;
			return (string)o;
		}
		set
		{
			ViewState["HandlerID"] = value;
		}
	}
	/// <summary>
	/// Stores the ID of the definition being edited
	/// </summary>
	public int DefinitionID
	{
		get
		{
			object o = ViewState["DefinitionID"];
			if (o == null) return -1;
			return (int)o;
		}
		set
		{
			ViewState["DefinitionID"] = value;
		}
	}
	/// <summary>
	/// Stores the ID of the process being edited
	/// </summary>
	public int ProcessID
	{
		get
		{
			object o = ViewState["ProcessID"];
			if (o == null) return -1;
			return (int)o;
		}
		set
		{
			ViewState["ProcessID"] = value;
		}
	}
	#endregion
	#region Page Load Event
	/// <summary>
	/// Page Load event
	/// </summary>
	/// <param name="sender"></param>
	/// <param name="e"></param>
	protected void Page_Load(object sender, EventArgs e)
	{
		if (!Page.IsPostBack)
		{
			// Store any state information from the calling listing
			this.HandlerID = GetAttribute("HandlerID", "");
			this.DefinitionID = GetAttribute("DefinitionID", -1);
			this.ProcessID = GetAttribute("ProcessID", -1);
			// Load info 
			Handler h = new Handlers().GetHandlerByID( this.HandlerID );
			if( h == null ) GoBack();
			Definition d = new Definitions().GetByID( this.DefinitionID );
			if( d == null ) GoBack();
			Process p = new Processes().GetProcessByID( this.ProcessID );
			if( p == null ) GoBack();
			
			// Display infos
			labHandler.Text = h.Name;
			labDefinition.Text = d.DefName;
			labProcess.Text = p.ProcessName;
			
			// Load the process
			ProcessName.Text = p.ProcessName;
			Rank.Text = p.Rank.ToString();
			ProcessType.SelectedValue = ((int) p.ProcessType).ToString();
			DataCanView.Checked = p.DataCanView;
			DataCanEdit.Checked = p.DataCanEdit;

			// Bind the various data grids
			BindAvailableActions();
			BindStartupActions();
			BindTaskings();
		}
	}
	#endregion
	#region Initialisation
	/// <summary>
	/// Capture events etc for grids 
	/// </summary>
	protected void Page_Init()
	{
		startupgrid.ItemDataBound += new DataGridItemEventHandler(startupgrid_ItemDataBound);
		startupgrid.ItemCommand += new DataGridCommandEventHandler(startupgrid_ItemCommand);
		taskingsgrid.ItemCommand += new DataGridCommandEventHandler(taskingsgrid_ItemCommand);
	}
	#endregion
	#region Navigation
	/// <summary>
	/// Returns to the listing, restoring state
	/// </summary>
	protected void GoBack()
	{
		string url = String.Format(
			"ui_Processes.aspx?HandlerID={0}&DefinitionID={1}", 
			this.HandlerID,
			this.DefinitionID);
		
		Response.Redirect(url, true);
	}
	#endregion
	#region Save/Cancel handlers
	/// <summary>
	/// User clicked the back to process list button
	/// </summary>
	/// <param name="sender"></param>
	/// <param name="e"></param>
	protected void btnBack_Click(object sender, EventArgs e)
	{
		GoBack();
	}
	/// <summary>
	/// User clicked the save button, update the data
	/// </summary>
	/// <param name="sender"></param>
	/// <param name="e"></param>
	protected void btnSave_Click(object sender, EventArgs e)
	{
		if (!Page.IsValid) return;
		
		Processes procs = new Processes();
		Process p = procs.GetProcessByID( this.ProcessID );
		if( p == null ) GoBack();

		// Update values
		p.ProcessName = this.ProcessName.Text;
		
		if( ProcessType.SelectedValue == "0" )
			p.ProcessType = Deepcode.Flux.Core.Systems.Workflow.Enums.WorkflowProcessType.PROCESS_WAIT;
		else
			p.ProcessType = Deepcode.Flux.Core.Systems.Workflow.Enums.WorkflowProcessType.PROCESS_CLEAR;

		p.Rank = Int32.Parse(this.Rank.Text);
		p.DataCanView = this.DataCanView.Checked;
		p.DataCanEdit = this.DataCanEdit.Checked;

		procs.Save( p );

		QuickAudit.RaiseInformation(
			new AuditUser(),
			"Flux", "Workflow Manager",
			"edited workflow process ({0}) in ({1})",
			p.ProcessName,
			p.ParentDefinition.DefName );
	}
	#endregion
	#region Startup Actions Grid
	/// <summary>
	/// Associates all of the available actions for this handler with the 
	/// available actions drop down list in startup actions
	/// </summary>
	protected void BindAvailableActions()
	{
		WorkflowEngine e = new WorkflowEngine( HandlerID );
		if( e == null ) return;

		ddlActions.Items.Clear();
		
		foreach( WorkflowMethodInfo winfo in e.GetWorkflowMethods())
		{
			string details = String.Format("{0} ({1})", winfo.FriendlyName, winfo.MethodName );
			ddlActions.Items.Add( new ListItem( details, winfo.MethodName ));
		}
	}
	/// <summary> 
	/// Bind the startup actions for this process to the appropriate grid
	/// </summary>
	protected void BindStartupActions()
	{
		Process p = new Processes().GetProcessByID(this.ProcessID);
		if (p == null) return;

		this.startupgrid.BindJavascript( "btnSUDelete", "onclick", "return ConfirmDeleteAction();" );
		
		this.startupgrid.DataSource = p.ProcessStartActions;
		this.startupgrid.DataBind();
	}
	/// <summary>
	/// Respond to an item being bound to the grid.
	/// This will show/hide the properties button for methods
	/// that do or do not have a properties form
	/// </summary>
	/// <param name="sender"></param>
	/// <param name="e"></param>
	void startupgrid_ItemDataBound(object sender, DataGridItemEventArgs e)
	{
		if ((e.Item.ItemType == ListItemType.Item) ||
			(e.Item.ItemType == ListItemType.AlternatingItem) ||
			(e.Item.ItemType == ListItemType.SelectedItem))
		{
			WorkflowEngine Engine = new WorkflowEngine( HandlerID );
			ProcessStart item = (ProcessStart)e.Item.DataItem;
			WorkflowMethodInfo iteminfo = Engine.GetWorkflowMethodInfo( item.Method );
			if( iteminfo == null ) return;
			// Determine if the properties link should appear
			if (!iteminfo.HasConfig)
			{
				LinkButton btn = (LinkButton) e.Item.FindControl("btnSUProperties");
				if (btn != null) btn.Visible = false;
			}
		}
	}
	/// <summary>
	/// Startup action being added to the process
	/// </summary>
	/// <param name="sender"></param>
	/// <param name="e"></param>
	protected void btnAddAction_Click(object sender, EventArgs e)
	{
		// Add the new startup action, with automated rank setting etc.
		Process p = new Processes().GetProcessByID( this.ProcessID );
		if( p == null ) return;

		p.AddProcessStart( this.ddlActions.SelectedValue );

		QuickAudit.RaiseInformation(
			new AuditUser(),
			"Flux", "Workflow Manager",
			"added startup action ({0}) to process ({1})",
			this.ddlActions.SelectedValue,
			p.ProcessName);

		this.BindStartupActions();
	}
	/// <summary>
	/// User has invoked an option on one of the associated startup actions
	/// </summary>
	/// <param name="source"></param>
	/// <param name="e"></param>
	void startupgrid_ItemCommand(object source, DataGridCommandEventArgs e)
	{
		if (e.Item.ItemType == ListItemType.Footer ||
			e.Item.ItemType == ListItemType.Header ||
			e.Item.ItemType == ListItemType.Pager ||
			e.Item.ItemType == ListItemType.Separator) return;

		// Get the key of the row being actioned 
		int rowKey = (int) startupgrid.DataKeys[e.Item.ItemIndex];

		// PROCESS COMMANDS
		if (e.CommandName == "ItemDelete")
		{
			ProcessStarts ps = new ProcessStarts();
			ProcessStart p = ps.GetProcessStartByID( rowKey );
			if( p == null ) return;

			ps.DeleteByID( rowKey );
			this.BindStartupActions();

			QuickAudit.RaiseInformation(
				new AuditUser(),
				"Flux", "Workflow Manager",
				"deleted startup action ({0}) from process ({1})",
				p.Method,
				p.ParentProcess.ProcessName);
		}

		if (e.CommandName == "ItemUp")
		{
			ProcessStarts ps = new ProcessStarts();
			ps.ShuffleUp( rowKey );
			this.BindStartupActions();
		}

		if (e.CommandName == "ItemDown")
		{
			ProcessStarts ps = new ProcessStarts();
			ps.ShuffleDown( rowKey );
			this.BindStartupActions();
		}

		if (e.CommandName == "ItemProperties")
		{
			string url = String.Format(
				"ui_startupactionprop.aspx?HandlerID={0}&DefinitionID={1}&ProcessID={2}&ProcessStartID={3}",
				this.HandlerID,
				this.DefinitionID,
				this.ProcessID,
				rowKey );

			Response.Redirect( url, true );
		}
	}
	#endregion
	#region Taskings Grid
	/// <summary>
	/// Bind the taskings for this process to the appropriate grid
	/// </summary>
	protected void BindTaskings()
	{
		Process p = new Processes().GetProcessByID( this.ProcessID );
		if( p == null ) return;

		this.taskingsgrid.BindJavascript( "btnTDelete", "onclick", "return ConfirmDeleteTasking();");

		this.taskingsgrid.DataSource = p.ProcessTaskings;
		this.taskingsgrid.DataBind();
	}
	/// <summary>
	/// Opens form for new user tasking
	/// </summary>
	/// <param name="sender"></param>
	/// <param name="e"></param>
	protected void btnAddUserTasking_Click(object sender, EventArgs e)
	{
		string url = String.Format(
			"ui_newusertask.aspx?HandlerID={0}&DefinitionID={1}&ProcessID={2}",
			this.HandlerID,
			this.DefinitionID,
			this.ProcessID);

		Response.Redirect(url, true);
	}
	/// <summary>
	/// Opens form for new system tasking
	/// </summary>
	/// <param name="sender"></param>
	/// <param name="e"></param>
	protected void btnAddSystemTasking_Click(object sender, EventArgs e)
	{
		string url = String.Format(
			"ui_newsystemtask.aspx?HandlerID={0}&DefinitionID={1}&ProcessID={2}",
			this.HandlerID,
			this.DefinitionID,
			this.ProcessID);

		Response.Redirect(url, true);
	}
	/// <summary>
	/// Action occurred on the taskings grid
	/// </summary>
	/// <param name="source"></param>
	/// <param name="e"></param>
	void taskingsgrid_ItemCommand(object source, DataGridCommandEventArgs e)
	{
		if( e.Item.ItemType == ListItemType.Footer ||
			e.Item.ItemType == ListItemType.Header || 
			e.Item.ItemType == ListItemType.Pager || 
			e.Item.ItemType == ListItemType.Separator ) return;

		// Get the key of the row being actioned 
		int rowKey = (int) taskingsgrid.DataKeys[ e.Item.ItemIndex ];

		// PROCESS COMMANDS
		if (e.CommandName == "ItemDelete")
		{
			Taskings tasks = new Taskings();
			Tasking  task = tasks.GetTaskingByID( rowKey );
			if( task == null ) return;
			
			tasks.DeleteByID( rowKey );
			BindTaskings();

			QuickAudit.RaiseInformation(
				new AuditUser(),
				"Flux", "Workflow Manager",
				"deleted tasking ({0}) from process ({1})",
				task.TaskCaption,
				task.ParentProcess.ProcessName);
		}

		if (e.CommandName == "ItemEdit")
		{
			Taskings tasks = new Taskings();
			Tasking  task = tasks.GetTaskingByID( rowKey );
			if( task == null ) return;

			string url = "";

			if (task.SystemTask)
			{
				url = String.Format(
					"ui_systemtask.aspx?HandlerID={0}&DefinitionID={1}&ProcessID={2}&TaskingID={3}",
					this.HandlerID,
					this.DefinitionID,
					this.ProcessID,
					rowKey);
			}
			else
			{
				url = String.Format(
					"ui_usertask.aspx?HandlerID={0}&DefinitionID={1}&ProcessID={2}&TaskingID={3}",
					this.HandlerID,
					this.DefinitionID,
					this.ProcessID,
					rowKey);
			}

			Response.Redirect(url, true);
		}
	}
	#endregion
}
